package com.bright.ghj.overt.manager.impl;

import com.bright.ghj.common.util.StringUtil;
import com.bright.ghj.overt.constant.PublicConstant;
import com.bright.ghj.overt.converter.FileItemConverter;
import com.bright.ghj.overt.converter.FileListConverter;
import com.bright.ghj.overt.converter.FilelistFooterConverter;
import com.bright.ghj.overt.converter.MainModalConverter;
import com.bright.ghj.overt.enums.FieldAlign;
import com.bright.ghj.common.enums.FieldType;
import com.bright.ghj.overt.enums.PublicType;
import com.bright.ghj.overt.manager.FileListManager;
import com.bright.ghj.overt.pojo.dto.FileItemDTO;
import com.bright.ghj.overt.pojo.dto.FileListDTO;
import com.bright.ghj.overt.pojo.dto.FilelistCwgkFooterDto;
import com.bright.ghj.overt.pojo.dto.MainModalDTO;
import com.bright.ghj.overt.pojo.po.primary.*;
import com.bright.ghj.overt.repository.primary.*;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author hxj
 * @Date 2023/12/22 14:45
 * @Description
 */
@Component
@RequiredArgsConstructor
public class FileListManagerImpl implements FileListManager {

    private final FileListConverter fileListConverter;
    private final FileItemConverter fileItemConverter;
    private final MainModalConverter mainModalConverter;
    private final FilelistFooterConverter filelistFooterConverter;

    private final FilelistRepository filelistRepository;
    private final FileItemRepository fileItemRepository;
    private final MainModalRepository mainModalRepository;
    private final FilelistCwgkFooterRepository filelistCwgkFooterRepository;
    private final NavigateButtonCwgkRepository buttonRepository;



    @Override
    @Cacheable(value = "FileList", key = "#root.methodName + '_' + #fileName")
    public FileListDTO getFileListByCache(String fileName) {
        FileList fileList = filelistRepository.getFileListByFileName(fileName);
        FileListDTO fileListDTO = fileListConverter.poConvertDTO(fileList);
        if (fileList != null) {
            // 赋值公开类型
            PublicType publicType = getPublicType(fileList.getFileType());
            fileListDTO.setPublicType(publicType);
            // 要区分如果主表不是子表之一的情况 fileList的notSubTable 默认为false 这里主动设值避免空指针
            if (fileListDTO.getNotSubTable() == null) {
                fileListDTO.setNotSubTable(false);
            }
        }

        return fileListDTO;
    }

    @Override
    @Cacheable(value = "FileItem", key = "#root.methodName + '_' + #tableName")
    public List<FileItemDTO> listFileItemsByCache(String tableName) {
        List<FileItem> fileItems = fileItemRepository.findFileItemByFilename(tableName);
        List<FileItemDTO> fileItemDTOS = fileItemConverter.poConvertDTO(fileItems);

        for (int i = 0; i < fileItemDTOS.size(); i++) {
            FileItemDTO fileItemDTO = fileItemDTOS.get(i);
            FileItem fileItem = fileItems.get(i);
            // 字段全部以大写返回
            fileItemDTO.setFieldName(StringUtil.upperCase(fileItemDTO.getFieldName()));
            // 字段类型
            String typeOfField = StringUtil.trim(fileItem.getTypeOfField());
            FieldType fieldType;
            // 对齐方式
            FieldAlign fieldAlign;
            if (StringUtil.equalsIgnoreCase(typeOfField, "D")
                    // 旧项目 M类型也是日期之意
                    || StringUtil.equalsIgnoreCase(typeOfField, "M")) {
                fieldType = FieldType.DATE;
                fieldAlign = FieldAlign.CENTER;
            } else if (StringUtil.equalsIgnoreCase(typeOfField, "N")) {
                fieldType = FieldType.NUMBER;
                fieldAlign = FieldAlign.RIGHT;
            } else if (StringUtil.equalsIgnoreCase(typeOfField, "M2")) {
                fieldType = FieldType.MULTI_TEXT;
                fieldAlign = FieldAlign.LEFT;
            } else if (StringUtil.equalsIgnoreCase(typeOfField, "B")) {
                fieldType = FieldType.BOOL;
                fieldAlign = FieldAlign.LEFT;
            } else {
                fieldType = FieldType.CHAR;
                fieldAlign = FieldAlign.LEFT;
            }
            fileItemDTO.setFieldType(fieldType);
            fileItemDTO.setFieldAlign(fieldAlign);

            if (fileItemDTO.getIsEncrypt() == null) {
                fileItemDTO.setIsEncrypt(false);
            }
        }
        return fileItemDTOS;
    }

    @Override
    @Cacheable(value = "MainModalByMenuId", key = "#root.methodName + '_' + #menuId")
    public List<MainModalDTO> listMainModalByMenuIdByCache(String menuId) {
        List<MainModal> mainModalList = mainModalRepository.findMainModalStartsWithModalId(menuId);

        // 封装成返回前端的格式 隐藏掉如selectDataSql之类的字段
        List<MainModalDTO> mainModalDTOS = new ArrayList<>();
        for (MainModal mainModal : mainModalList) {
            MainModalDTO mainModalDTO = mainModalConverter.poConvertDTO(mainModal);
            setSubMainModal(mainModalDTO);

            // 获取该表的公开类型
            PublicType publicType = getPublicType(mainModal.getDefMonths());
            mainModalDTO.setPublicType(publicType);
            mainModalDTOS.add(mainModalDTO);
        }
        return mainModalDTOS;
    }

    @Override
    @Cacheable(value = "MainModalByTableName", key = "#root.methodName + '_' + #tableName")
    public MainModalDTO getMainModalByTableName(String tableName) {
        List<MainModal> mainModalList = mainModalRepository.listMainModalByTableName(tableName);
        if (mainModalList.size() == 0) {
            throw new RuntimeException("mainModal未配置表名" + tableName);
        }
        // 如果出现同一个tableName多条mainModal配置，默认取第一个，若取不对则需调整配置表的isShow字段
        MainModalDTO mainModal = mainModalConverter.poConvertDTO(mainModalList.get(0));

        setSubMainModal(mainModal);
        return mainModal;
    }

    @Override
    @Cacheable(value = "MainModalById", key = "#root.methodName + '_' + #mainModalId")
    public MainModalDTO getMainModalById(Integer mainModalId) {
        MainModal mainModal = mainModalRepository.getOne(mainModalId);
        MainModalDTO mainModalDTO = mainModalConverter.poConvertDTO(mainModal);
        setSubMainModal(mainModalDTO);
        return mainModalDTO;
    }

    private void setSubMainModal(MainModalDTO mainModalDTO) {
        // 获取子表的mainModal（其实是同一samePageTab的其他mainModal）
        if (mainModalDTO.getSamePageTab() != null && mainModalDTO.getSamePageTab() != 0) {
            List<MainModalDTO> subModals = new ArrayList<>();
            for (MainModal subModal : mainModalRepository.findMainModalsBySamePageTab(mainModalDTO.getSamePageTab())) {
                // 由于上面的方法会把主表一起返回来 这里要把主表挑掉 只保留子表
                if (!StringUtil.equalsIgnoreCase(subModal.getTableName(), mainModalDTO.getTableName())) {
                    subModals.add(mainModalConverter.poConvertDTO(subModal));
                }
            }
            mainModalDTO.setSubMainModalList(subModals);
        }
    }

    @Override
    @Cacheable(value = "FilelistCwgkFooter", key = "#root.methodName + '_' + #fileName")
    public List<FilelistCwgkFooterDto> getFooterByFileName(String fileName) {
        // 先获取这个fileName看有没有特例
        List<FilelistCwgkFooter> footers = filelistCwgkFooterRepository.findFilelistCwgkFootersByFileName(fileName);
        if (footers.size() == 0) {
            // 没有再获取有没有在数据库中指定所有表的通用脚注配置
            footers = filelistCwgkFooterRepository.findFilelistCwgkFootersByFileName(PublicConstant.FOOTER_CONFIG_COMMON_KEY);
        }
        if (footers.size() > 0) {
            return filelistFooterConverter.poConvertDTO(footers);
        }
        // 返回默认脚注
        return PublicConstant.DEFAULT_FOOTER_LIST;
    }

    @Override
    @Cacheable(value = "NavigateButtonCwgk", key = "#root.methodName + '_' + #fileName")
    public List<NavigateButtonCwgk> getButtonsByFileName(String fileName) {
        return buttonRepository.getByFileName(fileName);
    }

    // 获取公开类型
    private PublicType getPublicType(String fileType) {
        if (StringUtil.equals(fileType, "年报") || StringUtil.equals(fileType, "年初报")) {
            return PublicType.YEAR;
        }
        if (StringUtil.equals(fileType, "半年报")) {
            return PublicType.HALF_YEAR;
        }
        if (StringUtil.equals(fileType, "季报")) {
            return PublicType.SEASON;
        }
        if (StringUtil.equals(fileType, "周报")) {
            return PublicType.WEEK;
        }
        if (StringUtil.equals(fileType, "及时")) {
            return PublicType.TIMELY;
        }
        return PublicType.MONTH;
    }
}
